﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TinyPinyin;

namespace Shinva.Variables.Helper
{
    /// <summary>  
    /// 变量名生成器，将输入字符串转换为符合要求的变量名。  
    /// 包括中文拼音转换（使用TinyPinyin）、驼峰规则、下划线分隔、以及通过工具类检查变量名合法性。  
    /// </summary>  
    public static class VariableNameGenerator
    {
        // 使用字典记录生成的变量名和出现次数，保证名称唯一  
        private static readonly Dictionary<string, int> _generatedNames = new Dictionary<string, int>();

        /// <summary>  
        /// 将输入字符串转换为变量名。  
        /// 1. 遍历字符串，将中文字符转换为拼音（小写）并存入缓冲区，  
        ///    非中文字符直接累加至英文缓冲区。  
        /// 2. 连续中文转换为驼峰命名法后与英文部分以“_”连接。  
        /// 3. 使用工具类检查及修正生成的变量名（特殊符号替换、关键字检测等）。  
        /// 4. 将变量名首字母大写，并保证生成名称唯一（重复则添加 _数字 后缀）。  
        /// </summary>  
        public static  string Convert(string input)
        {
            // 用于保存分段（中文拼音或英文及其它字符）  
            List<string> segments = new List<string>();
            // 用于累积连续中文字符转换后的拼音  
            List<string> chineseBuffer = new List<string>();
            // 用于累积非中文字符  
            StringBuilder englishBuffer = new StringBuilder();

            // 遍历每个字符  
            foreach (char c in input)
            {
                if (IsChinese(c))
                {
                    // 如果遇到中文字符，则先处理已有的英文缓冲区  
                    if (englishBuffer.Length > 0)
                    {
                        segments.Add(englishBuffer.ToString());
                        englishBuffer.Clear();
                    }
                    // 利用 TinyPinyin 库转换为拼音（结果为小写）  
                    string pinyin = PinyinHelper.GetPinyin(c.ToString()).ToLower();
                    chineseBuffer.Add(pinyin);
                }
                else
                {
                    // 如果遇到非中文字符，则先判断中文缓冲区中是否有内容  
                    if (chineseBuffer.Count > 0)
                    {
                        segments.Add(ConvertToCamel(chineseBuffer));
                        chineseBuffer.Clear();
                    }
                    englishBuffer.Append(c);
                }
            }

            // 处理剩余的中文或英文缓冲区  
            if (chineseBuffer.Count > 0)
            {
                segments.Add(ConvertToCamel(chineseBuffer));
            }
            if (englishBuffer.Length > 0)
            {
                segments.Add(englishBuffer.ToString());
            }

            // 使用下划线连接各个分段  
            string variableName = string.Join("_", segments);

            // 使用工具类检查与修正变量名是否合法（替换特殊符号、关键字等）  
            variableName = CVariableNameUtil.EnsureValidIdentifier(variableName);

            // 将生成的变量名首字母大写  
            variableName = Capitalize(variableName);

            // 保证生成的变量名唯一，如果名称重复则在后面添加 _数字 后缀  
            if (_generatedNames.ContainsKey(variableName))
            {
                int count = _generatedNames[variableName];
                _generatedNames[variableName] = count + 1;
                variableName = variableName + "_" + count;
            }
            else
            {
                _generatedNames[variableName] = 1;
            }

            return variableName;
        }

        /// <summary>  
        /// 判断字符是否为中文（利用 Unicode 范围判断：\u4e00 ~ \u9fff）。  
        /// </summary>  
        private static bool IsChinese(char c)
        {
            return c >= '\u4e00' && c <= '\u9fff';
        }

        /// <summary>  
        /// 将中文拼音列表转换为驼峰格式：  
        /// 第一个单词全小写，其后单词首字母大写，其余小写  
        /// 例如：["zhang", "shan"] → "zhangShan"  
        /// </summary>  
        private static string ConvertToCamel(List<string> syllables)
        {
            if (syllables.Count == 0)
                return string.Empty;

            StringBuilder sb = new StringBuilder();
            // 第一个单词全部小写  
            sb.Append(syllables[0].ToLower());
            // 后续单词处理：首字母大写，其余小写  
            for (int i = 1; i < syllables.Count; i++)
            {
                if (!string.IsNullOrEmpty(syllables[i]))
                {
                    sb.Append(char.ToUpper(syllables[i][0]));
                    if (syllables[i].Length > 1)
                    {
                        sb.Append(syllables[i].Substring(1).ToLower());
                    }
                }
            }
            return sb.ToString();
        }

        /// <summary>  
        /// 将字符串的首字母转换为大写  
        /// </summary>  
        private static string Capitalize(string s)
        {
            if (string.IsNullOrEmpty(s))
                return s;
            return char.ToUpper(s[0]) + s.Substring(1);
        }
    }

}
